﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;
using FBEntities.FBConnections.User;
using FBEntities.FBObjects;
using FBEntities.FBObjects.User;
using XDAFacebook;
using XFControls.Utils;
using XFControls.XFPanels.XFPanelModals;
using XFItemControls.XFPanels.XFPanelItems;
using XFSenseUI.XFItems;
using XFSenseUI.XFItems.SenseControls;

#pragma warning disable 1591
#pragma warning disable 649

namespace XFControls.XFPanels.XFPanelItems
{
    public sealed class XFItemPost : XFItemBase, IXFItemSwipeable
    {
        private readonly SenseControlButton _delete;
        private readonly int _maxLeft;
        private readonly Font _nameFont;
        private readonly Font _timeFont;
        private const int _descLimit = 200;
        private int _height;
        private const int _iconWidth = 16;
        private bool _inSwipe;
        private int _left;
        private const int _lineSpace = 5;
        private const int _maxFriends = 4;
        private readonly int _pictureWidth = Settings.IconSize;
        private readonly int _postPictureWidth = Settings.ImageSize;
        private WebDownloaderWrapper _deleteWrapper;
        private XFItemPostSelected _clicked;
        private Rectangle _commentsRec;
        private Rectangle _deleteRec;
        private Rectangle _likesRec;
#pragma warning restore 649
        private Rectangle _nameRec;
        private Rectangle _pictureRec;
        private Rectangle _profileRec;
        private Rectangle _toAndFromRec;
        private Rectangle _messageRec;
        private Rectangle _iconRec;
        private Rectangle _captRec;
        private Rectangle _descRec;
        private Rectangle _timeRec;
        private static Bitmap _actionImage;
        private UpdateEventHandler _userUpdateEvent;
        private string _toString;
        public bool _isInCommentPannel = false;

        public XFItemPost(FBPost post)
        {
            Post = post;
            _height = -1;
            _maxLeft = GetWidth() >> 1;
            _delete = new SenseControlButton(Settings.LocalizationStrings.Delete);
            _delete.Style.Padding = 25;
            _delete.Style.PaddingTop = 10;
            _delete.Style.PaddingBottom = 10;
            _delete.Clicked += (o, e) =>
                                   {
                                       Cursor.Current = Cursors.WaitCursor;
                                       Application.DoEvents();

                                       _deleteWrapper = Post.Delete();

                                       _deleteWrapper.GetResults += (wo, we) =>
                                                                    {
                                                                        if (FBParseUtilities.HasError(we.Text))
                                                                            Visible = false;
                                                                        else
                                                                            MessageBox.Show(Settings.LocalizationStrings.ErrorDeletingPost);

                                                                        if (Parent is XFPanelList)
                                                                            ((XFPanelList)Parent).Resize();
                                                                        Parent.Invalidate();

                                                                        Cursor.Current = Cursors.Default;
                                                                        Application.DoEvents();
                                                                    };
                                       _deleteWrapper.BeginDelete();
                                   };

            Style = new XFItemStyle
                        {
                            BackgroundColor = Color.White,
                            SelectedBackgroundColor = Color.Lavender,
                            TextFont = new Font(FontFamily.GenericSansSerif, 8, FontStyle.Regular),
                            TextColor = Color.Black,
                            SecondaryTextFont = new Font(FontFamily.GenericSansSerif, 8, FontStyle.Underline),
                            SecondaryTextColor = Color.Navy,
                            DashStyleBottom = DashStyle.Solid,
                            BorderBottomColor = Color.DarkGray,
                            Padding = 5
                        };

            _nameFont = new Font(Style.TextFont.Name, Style.TextFont.Size, FontStyle.Bold);
            _timeFont = new Font(Style.TextFont.Name, Style.TextFont.Size - 1, FontStyle.Bold);


            if (Post != null)
            {
                if (post.type == "comment")
                    Style.BackgroundColor = Color.LightGray;


                if (_userUpdateEvent == null)
                    _userUpdateEvent = (o, e) =>
                    {
                        var par = Parent as XFPanelList;
                        ResetHeight();

                        Invalidate();
                        if (par == null) return;
                        par.ClearAnimationItem(this);

                        if (!par.IsDisposed)
                            par.Damage();
                    };

                Post.Updated += _userUpdateEvent;
            }
            ItemType = XFItemType.Clickable;
            _iconRec = new Rectangle(Style.PaddingLeft, Style.PaddingTop, _pictureWidth, _pictureWidth);

            if (post.from != null && XFItemControlUtils.Me != null && post.from.id == XFItemControlUtils.Me.Me.id)
            {
                ItemType = XFItemType.Swipable;
            }
        }

        public FBPost Post { get; set; }
        public bool FullText { get; set; }
        public object Tag { get; set; }

        public override int GetHeight()
        {
            if (!Visible)
                return 0;

            if (Post == null)
                return _pictureWidth + Style.PaddingTop + Style.PaddingBottom;

            if (_height > 0)
                return _height;

            Rendered = false;
            int width = GetWidth();
            int currX = Style.PaddingLeft + _pictureWidth + Style.PaddingRight;
            int currY = Style.PaddingTop;
            int offset = 0;
            _profileRec = new Rectangle(0, 0, _iconWidth + _lineSpace, _iconWidth + _lineSpace);

            int bodyWidth = width - (currX + Style.PaddingRight + Style.PaddingLeft);
            int bodyWidthPic = width - (currX + Style.PaddingRight + Style.PaddingLeft) -
                               (_postPictureWidth + Style.PaddingRight);
            int currWidth = bodyWidth;
            int temp = 0;
            string toAndFrom = GetToFromString(Post);
            string desc = string.IsNullOrEmpty(Post.description) ? "" : Post.description;

            if (desc.Length > _descLimit && !FullText)
                desc = desc.Substring(0, _descLimit) + "...";

            int recTemp = currY;
            _toAndFromRec = new Rectangle(currX, recTemp, currWidth, 0)
                           {
                               Height = MesText(toAndFrom, ref currWidth, ref temp, ref currY, bodyWidth)
                           };

            _messageRec = new Rectangle(currX, currY, currWidth, 0)
                          {
                              Height = MesText(Post.message, ref currWidth, ref temp, ref currY, bodyWidth)
                          };

            currY += _lineSpace;
            temp = 0;

            if (!string.IsNullOrEmpty(Post.picture))
            {
                offset = currWidth - bodyWidthPic + Style.PaddingRight;
                _pictureRec = new Rectangle(currX, currY, _postPictureWidth, _postPictureWidth);
                currWidth = bodyWidthPic;
            }

            recTemp = currY;
            _nameRec = new Rectangle(currX + offset, recTemp, currWidth, 0);

            using (var f = new Font(Style.TextFont.Name, Style.TextFont.Size, FontStyle.Bold))
                _nameRec.Height = MesText(Post.name, ref currWidth, ref temp, ref currY, bodyWidth, f);

            if (currWidth != bodyWidthPic)
                offset = 0;

            _captRec = new Rectangle(currX + offset, currY, currWidth, 0)
                       {
                           Height = MesText(Post.caption, ref currWidth, ref temp, ref currY, bodyWidth)
                       };

            if (currWidth != bodyWidthPic)
                offset = 0;

            _descRec = new Rectangle(currX + offset, currY, currWidth, 0)
                       {
                           Height = MesText(desc, ref currWidth, ref temp, ref currY, bodyWidth)
                       };


            if (!string.IsNullOrEmpty(Post.picture) && temp < _postPictureWidth)
            {
                currWidth = bodyWidth;
                currY += _postPictureWidth - temp + _lineSpace;
            }

            _timeRec = new Rectangle(currX, currY, currWidth, 0)
                       {
                           Height = MesText(Post.updated_time.ToFacebookTime(), ref currWidth, ref temp, ref currY, bodyWidth)
                       };

            if (Post.actions.Count > 0 || Post.type == "comment" || Post.type == "Photo")
            {
                if (_actionImage == null)
                    GetActionImage();
                currY += _actionImage.Height;
            }

            _height = currY + Style.PaddingBottom;

            return _height;
        }

        public override void ResetHeight()
        {
            _height = -1;
        }

        public override void ItemPaint(Graphics g, int x, int y)
        {
            if (Post == null)
                return;

            if (_left > 0)
            {
                DrawLeft(g);
            }
            base.ItemPaint(g, x - _left, y);

            string toAndFrom = GetToFromString(Post);
            string desc = string.IsNullOrEmpty(Post.description) ? "" : Post.description;

            Color textColor = getCurrentFontColor(false);
            Color secondaryTextColor = getCurrentFontColor(false);

            _iconRec.X = Style.PaddingLeft - _left;

            if (Post.from != null && !string.IsNullOrEmpty(Post.from.name))
                DrawIcon(Post.from.Picture.url, g, _iconRec);
            else if (Post.type != "groups")
                DrawUI("iconThumb", g, _iconRec);

            g.DrawString(toAndFrom, _toAndFromRec, XFItemTextAlign.Left, Style.TextFont, secondaryTextColor);
            g.DrawString(Post.message, _messageRec, XFItemTextAlign.Left, Style.TextFont, textColor);
            g.DrawString(Post.name, _nameRec, XFItemTextAlign.Left, _nameFont, textColor);
            g.DrawString(Post.caption, _captRec, XFItemTextAlign.Left, Style.TextFont, Color.DarkGray);
            g.DrawString(desc, _descRec, XFItemTextAlign.Left, Style.TextFont, Color.Gray);

            _toString = toAndFrom + " - " + Post.message + " " + Post.name + " " + Post.caption + " " + desc;

            if (!string.IsNullOrEmpty(Post.picture))
            {
                var tempRec = new Rectangle(_pictureRec.X - _left, _pictureRec.Y, _pictureRec.Width, _pictureRec.Height);
                DrawImage(Post.picture, g, tempRec);
                //DrawUI("image", g, tempRec);
            }

            if (Post.type != "groups")
                WritePostTime(g);
            if (Post.type != "Photo" && Post.type != "comment" && Post.actions.Count <= 0) return;

            DrawActions(g);
        }

        private void DrawLeft(Graphics g)
        {
            using (var b = new SolidBrush(Color.LavenderBlush))
                g.FillRectangle(b, GetWidth() - _left, 0, _left, GetHeight());

            int buttonX = (GetWidth() >> 3) * 3;
            int buttonY = GetHeight() >> 2;

            buttonX += _delete.GetWidth() >> 2;
            buttonY += _delete.GetHeight() >> 2;

            _deleteRec = new Rectangle(buttonX, buttonY, _delete.GetWidth(), _delete.GetHeight());
            _delete.ItemPaint(g, buttonX, buttonY);

            using (var p = new Pen(Color.Black))
                g.DrawLine(p, GetWidth() - _left + 5, 0, GetWidth() - _left + 5, GetHeight());
        }

        public override XFItemClickResult GetClickResult()
        {
            if (_inSwipe)
            {
                if (_delete.State == XFItemState.Selected)
                {
                    _delete.State = XFItemState.Normal;

                    IXFModal modal = Parent.ShowModal(XFModal.Bottom, Settings.LocalizationStrings.DeletePost);

                    modal.OnSuccessAction += (o, e) => _delete.GetClickResult();
                    modal.State = XFModalState.Expanding;

                    return XFItemClickResult.CustomModal;
                }

                SlideRight();
                return XFItemClickResult.Nothing;
            }
            switch (_clicked)
            {
                case XFItemPostSelected.Like:
                    {
                        IXFModal modal = Parent.ShowModal(XFModal.Bottom, Settings.LocalizationStrings.likePost);

                        modal.OnSuccessAction += (o, e) =>
                                                     {
                                                         var par = Parent as XFPanelList;
                                                         if (par == null) return;
                                                         int loc = par[this];

                                                         var worker = new XFWorkerPostLike(Post, false);
                                                         var loading = new XFItemLoading(worker, false);

                                                         //var loadingAnimation = new XFItemAnimation(GetHeight(),
                                                         //                                           _likesRec.X + Style.PaddingLeft + 15,
                                                         //                                           _likesRec.Y + 25);

                                                         //loadingAnimation.SetStoryLine(XFControlUtils.GetCurrent_Directory() + "\\Resources\\loading.png", 8);
                                                         //par.AddAnimation(loadingAnimation, this);

                                                         loading.WorkFinished += (ob, ex) => Invalidate(); /*par.ClearAnimationItem(this);*/

                                                         par.Add(loading, loc);
                                                         loading.DoWork();
                                                     };
                        modal.State = XFModalState.Expanding;
                    }
                    return XFItemClickResult.CustomModal;
                case XFItemPostSelected.Comment:
                    {
                        if (Parent == null)
                            return XFItemClickResult.Nothing;

                        if (_isInCommentPannel)
                        {
                            if (Post.PeopleWhoLiked.count == 0)
                                return XFItemClickResult.Nothing;

                            XFPanelList rpl = GetLikesPanel(Post);

                            Parent.SetRightPanel(rpl);

                            rpl.ShowAlphaBar(false);
                            rpl.ShowScrollbar(true);
                            rpl.ScrollbarColor = Parent.ScrollbarColor;

                            break;
                        }

                        XFPanelList rp = GetCommentsPanel(Post);

                        Parent.SetRightPanel(rp);

                        rp.ShowAlphaBar(false);
                        rp.ShowScrollbar(true);
                        rp.ScrollbarColor = Parent.ScrollbarColor;
                    }
                    break;
                case XFItemPostSelected.Profile:
                    {
                        if (Parent == null)
                            return XFItemClickResult.Nothing;

                        FBPerson friendProf = Post.from.ToPerson();
                        //friendProf.Parse();

                        XFPanelList rp = XFItemControlUtils.SetupProfile(friendProf);

                        var back = new XFItemBackHeader();

                        if (Parent.Parent != null && Parent.Parent is XFPanelContainer)
                            ((XFPanelContainer)Parent.Parent).SetHeaderLeftButton(new XFButtonBack());

                        rp.AddHeaderItem(back);
                        Parent.SetRightPanel(rp);

                        rp.ShowAlphaBar(false);
                        rp.ShowScrollbar(true);
                    }
                    break;
                case XFItemPostSelected.Link:
                    if (!string.IsNullOrEmpty(Post.link))
                        System.Diagnostics.Process.Start(Post.link, null);
                    return XFItemClickResult.Nothing;
                case XFItemPostSelected.Picture:
                    if (Post.type == "link")
                    {
                        System.Diagnostics.Process.Start(Post.link, null);
                    }
                    else
                    {
                        Cursor.Current = Cursors.WaitCursor;
                        Application.DoEvents();

                        var photo = new FBPhoto(Post.link);

                        Cursor.Current = Cursors.Default;
                        Application.DoEvents();

                        if (photo.images != null && photo.images.Count > 0)
                            //System.Diagnostics.Process.Start(photo.images.First().source, null);
                            using (var viewer = new ImageViewer(photo))
                            {
                                if (viewer.ShowDialog() == DialogResult.Yes && !_isInCommentPannel)
                                {
                                    _clicked = XFItemPostSelected.Comment;
                                    return GetClickResult();
                                }
                            }

                        else
                        {
                            _clicked = XFItemPostSelected.Comment;
                            return GetClickResult();
                        }
                    }
                    return XFItemClickResult.Nothing;
                case XFItemPostSelected.Inbox:
                    {
                        if (Parent == null)
                            return XFItemClickResult.Nothing;

                        if (Parent.Name == Settings.LocalizationStrings.postDetailsHeaderTitle)
                            return XFItemClickResult.Nothing;

                        XFPanelList rp = GetCommentsPanel(Post);

                        Parent.SetRightPanel(rp);

                        rp.ShowAlphaBar(false);
                        rp.ShowScrollbar(true);
                        rp.ScrollbarColor = Parent.ScrollbarColor;
                    }
                    break;
                case XFItemPostSelected.Groups:
                    {
                        if (Parent == null || Tag == null || !(Tag is FBGroup))
                            return XFItemClickResult.Nothing;

                        XFPanelList rp = XFItemControlUtils.SetupGroup((FBGroup)Tag);

                        Parent.SetRightPanel(rp);

                        rp.ShowAlphaBar(false);
                        rp.ShowScrollbar(true);
                        rp.ScrollbarColor = Parent.ScrollbarColor;
                    }
                    break;
            }

            return XFItemClickResult.SlideLeft;
        }

        public override void OnMouseDown(int x, int y)
        {
            base.OnMouseDown(x, y);

            if (Post.type == "inbox")
            {
                _clicked = XFItemPostSelected.Inbox;
                return;
            }
            if (Post.type == "groups")
            {
                _clicked = XFItemPostSelected.Groups;
                return;
            }

            if (_deleteRec.Contains(x, y))
                _delete.OnMouseDown(5, 5);

            if (ItemType == XFItemType.Swipable && Parent is XFPanelList)
                ((XFPanelList)Parent).PanelReceiveSwipe = false;

            if (_commentsRec.Contains(new Point(x, y)))
                _clicked = XFItemPostSelected.Comment;

            else if (_likesRec.Contains(new Point(x, y)))
                _clicked = XFItemPostSelected.Like;

            else if (_pictureRec.Contains(new Point(x, y)))
                _clicked = XFItemPostSelected.Picture;

            else if (_nameRec.Contains(new Point(x, y)))
                _clicked = XFItemPostSelected.Link;

            else if (_profileRec.Contains(new Point(x, y)))
                _clicked = XFItemPostSelected.Profile;

            else if (_toAndFromRec.Contains(new Point(x, y)))
                _clicked = XFItemPostSelected.Profile;

            else _clicked = XFItemPostSelected.Comment;
        }

        public override void Dispose()
        {
            base.Dispose();
            _timeFont.Dispose();
            _nameFont.Dispose();
            Post.Updated -= _userUpdateEvent;

            if (_delete != null)
                _delete.Dispose();

            if (_deleteWrapper != null)
                _deleteWrapper.Dispose();
        }

        public override string ToString()
        {
            return _toString;
        }

        public void Swipe(Point start, Point end)
        {
            if (end.X < start.X && !_inSwipe)
            {
                SlideLeft();
            }
            else if (end.X > start.X && _inSwipe)
            {
                SlideRight();
            }
            else if (end.X > start.X)
            {
                if (Parent is XFPanelList)
                {
                    var list = Parent as XFPanelList;
                    if (list.HasBack)
                    {
                        list.EnableSlide();
                    }
                }
            }
        }

        private XFPanelList GetLikesPanel(FBPost post)
        {
            var rp = new XFPanelList();
            var back = new XFItemBackHeader();

            var worker = new XFWorkerLoadLikes(post);
            var loading = new XFItemLoading(worker);

            loading.WorkFinished += LikesLoaded;
            rp.PanelName = Settings.LocalizationStrings.Likes;

            if (!Post.PeopleWhoLiked.Parsed)
                rp.Add(loading);
            else
            {
                loading.Parent = rp;
                LikesLoaded(loading, new WorkerEventArgs(worker));
            }

            rp.AddHeaderItem(back);

            return rp;
        }

        public static XFPanelList GetCommentsPanel(FBPost post)
        {
            var rp = new XFPanelList();
            var back = new XFItemBackHeader();

            rp.Add(new XFItemPost(post) { FullText = true, _isInCommentPannel = true });

            var worker = new XFWorkerLoadComments(post);
            var loading = new XFItemLoading(worker);

            loading.WorkFinished += CommentsLoaded;

            rp.PanelName = Settings.LocalizationStrings.postDetailsHeaderTitle;
            rp.Add(loading);

            rp.AddHeaderItem(back);

            return rp;
        }

        private static void CommentsLoaded(object sender, WorkerEventArgs args)
        {
            FBPost parsedPost = null;
            if (args.Worker is XFWorkerLoadComments)
                parsedPost = ((XFWorkerLoadComments)args.Worker).ParsedPost;

            var par = (XFPanelList)((XFItemLoading)sender).Parent;
            if (par == null) return;

            var com = new XFItemAddComment(parsedPost);
            if (par.IsDisposed) return;

            par.Invoke(new Action(() =>
            {
                if (parsedPost == null || parsedPost.Comments == null)
                    return;

                if (parsedPost.type != "inbox")
                    par.Add(com);

                if (parsedPost.Comments.paging != null && !string.IsNullOrEmpty(parsedPost.Comments.paging.previous))
                {
                    var prev = new SenseItem
                    {
                        Tag = parsedPost.Comments.paging.previous,
                        MainText = Settings.LocalizationStrings.olderPosts
                    };

                    par.Add(prev);

                    prev.Click += PreviousExpand;
                }

                foreach (var p in parsedPost.Comments.data)
                {
                    var commentPost = new XFItemPost(p.ToPost()) { _isInCommentPannel = true };
                    par.Add(commentPost);
                }

                if (parsedPost.Comments.paging == null) return;
                var next = new SenseItem
                {
                    Tag = parsedPost.Comments.paging.next,
                    MainText = Settings.LocalizationStrings.newerPosts
                };

                next.Click += NextClick;
                next.Style.BackgroundColor = Color.White;
                par.Add(next);
            }));
        }

        private static void LikesLoaded(object sender, WorkerEventArgs args)
        {
            FBPost parsedPost = null;
            if (args.Worker is XFWorkerLoadLikes)
                parsedPost = ((XFWorkerLoadLikes)args.Worker).ParsedPost;

            var par = (XFPanelList)((XFItemLoading)sender).Parent;
            if (par == null) return;

            if (par.IsDisposed) return;

            if (par.InvokeRequired)
            {
                par.Invoke(new Action(() => LikesLoaded(sender, args)));
                return;
            }


            if (parsedPost == null || parsedPost.PeopleWhoLiked == null)
                return;

            if (parsedPost.PeopleWhoLiked.paging != null && !string.IsNullOrEmpty(parsedPost.PeopleWhoLiked.paging.previous))
            {
                var prev = new SenseItem
                {
                    Tag = parsedPost.PeopleWhoLiked.paging.previous,
                    MainText = Settings.LocalizationStrings.olderLikes
                };

                par.Add(prev);

                prev.Click += PreviousLikesExpand;
            }

            LoadLikes(par, parsedPost, -1);

            if (parsedPost.PeopleWhoLiked.paging == null) return;
            var next = new SenseItem
            {
                Tag = parsedPost.PeopleWhoLiked.paging.next,
                MainText = Settings.LocalizationStrings.newerLikes
            };

            next.Click += NextLikesClick;
            next.Style.BackgroundColor = Color.White;
            par.Add(next);

        }

        private static void LoadLikes(XFPanelList par, FBPost parsedPost, int count)
        {
            foreach (var p in parsedPost.PeopleWhoLiked.data)
            {
                var item = new SenseItem { MainText = p.name, Tag = p.id };
                FBObject curObject = p;
                item.Click += (o, e) =>
                                  {
                                      var friendProf = new FBPerson { id = curObject.id.ToString(), name = curObject.name };
                                      var rp = XFItemControlUtils.SetupProfile(friendProf);

                                      var back = new XFItemBackHeader();

                                      if (par.Parent != null && par.Parent is XFPanelContainer)
                                          ((XFPanelContainer)par.Parent).SetHeaderLeftButton(new XFButtonBack());

                                      rp.AddHeaderItem(back);
                                      par.SetRightPanel(rp);

                                      rp.ShowAlphaBar(false);
                                      rp.ShowScrollbar(true);
                                      par.EnableSlide();
                                  };

                if (count < 0)
                    par.Add(item);
                else
                    par.Add(item, count);
            }
        }

        private static void PreviousExpand(object sender, EventArgs e)
        {
            AsyncWebDownloader.ClearAsync();
            var button = (SenseItem)sender;
            var parent = (XFPanelList)button.Parent;

            if (parent == null) return;

            var worker = new XFWorkerLoadComments(button.Tag.ToString());
            var newLoading = new XFItemLoading(worker);

            newLoading.WorkFinished += PreviousExpandLoadingWorkFinished;

            parent.Add(newLoading, parent[button]);
            parent.ClearItem(button);
            button.Dispose();
        }

        private static void PreviousExpandLoadingWorkFinished(object sender, WorkerEventArgs e)
        {
            FBPost feed = null;
            var loading = (XFItemLoading)sender;

            if (e.Worker is XFWorkerLoadComments)
                feed = ((XFWorkerLoadComments)e.Worker).ParsedPost;

            var par = loading.Parent as XFPanelList;

            if (par != null && !par.IsDisposed)
                par.Invoke(new Action(() =>
                {
                    int loaderCount = par[loading];

                    par.ClearItem(loading);

                    if (feed == null || feed.Comments.data == null) return;

                    for (int i = feed.Comments.data.Count; i > 0; i--)
                    {
                        FBComment p = feed.Comments.data[i - 1];
                        var post = new XFItemPost(p.ToPost());
                        par.Add(post, loaderCount);
                        par.RenderItemBuffer(post, false);
                    }

                    if (feed.Comments.paging == null || string.IsNullOrEmpty(feed.Comments.paging.previous)) return;

                    var prev = new SenseItem
                    {
                        Tag = feed.Comments.paging.previous,
                        MainText = Settings.LocalizationStrings.olderPosts
                    };

                    par.Add(prev);

                    prev.Click += PreviousExpand;
                }));
        }

        private static void NextClick(object sender, EventArgs e)
        {
            var button = (SenseItem)sender;
            var parent = (XFPanelList)button.Parent;

            parent.ClearItem(button);

            var worker = new XFWorkerLoadComments(button.Tag.ToString());
            var loading = new XFItemLoading(worker);

            loading.WorkFinished += NextClickLoadingWorkFinished;
            button.Dispose();
            parent.Add(loading);
        }

        private static void NextClickLoadingWorkFinished(object sender, WorkerEventArgs e)
        {
            FBPost feed = null;
            var loading = (XFItemLoading)sender;

            if (e.Worker is XFWorkerLoadComments)
                feed = ((XFWorkerLoadComments)e.Worker).ParsedPost;

            var par = loading.Parent as XFPanelList;

            if (par != null && !par.IsDisposed)
                par.Invoke(new Action(() =>
                {
                    par.ClearItemsAfterWaiting(loading);

                    if (feed == null || feed.Comments.data == null) return;
                    foreach (FBComment p in feed.Comments.data)
                    {
                        var post = new XFItemPost(p.ToPost());
                        par.Add(post);
                        par.RenderItemBuffer(post, false);
                    }

                    if (feed.Comments.paging == null) return;
                    var next = new SenseItem
                    {
                        Tag = feed.Comments.paging.next,
                        MainText = Settings.LocalizationStrings.newerPosts
                    };

                    next.Click += NextClick;
                    next.Style.BackgroundColor = Color.White;
                    par.Add(next);
                }));
        }

        private static void PreviousLikesExpand(object sender, EventArgs e)
        {
            AsyncWebDownloader.ClearAsync();
            var button = (SenseItem)sender;
            var parent = (XFPanelList)button.Parent;

            if (parent == null) return;

            var worker = new XFWorkerLoadLikes(button.Tag.ToString());
            var newLoading = new XFItemLoading(worker);

            newLoading.WorkFinished += PreviousLikesExpandLoadingWorkFinished;

            parent.Add(newLoading, parent[button]);
            parent.ClearItem(button);
            button.Dispose();
        }

        private static void PreviousLikesExpandLoadingWorkFinished(object sender, WorkerEventArgs e)
        {
            FBPost feed = null;
            var loading = (XFItemLoading)sender;

            if (e.Worker is XFWorkerLoadLikes)
                feed = ((XFWorkerLoadLikes)e.Worker).ParsedPost;

            var par = loading.Parent as XFPanelList;

            if (par != null && !par.IsDisposed)
                par.Invoke(new Action(() =>
                {
                    int loaderCount = par[loading];

                    par.ClearItem(loading);

                    if (feed == null || feed.PeopleWhoLiked.data == null) return;

                    LoadLikes(par, feed, loaderCount);

                    if (feed.PeopleWhoLiked.paging == null || string.IsNullOrEmpty(feed.PeopleWhoLiked.paging.previous)) return;

                    var prev = new SenseItem
                    {
                        Tag = feed.PeopleWhoLiked.paging.previous,
                        MainText = Settings.LocalizationStrings.olderLikes
                    };

                    par.Add(prev);

                    prev.Click += PreviousLikesExpand;
                }));
        }

        private static void NextLikesClick(object sender, EventArgs e)
        {
            var button = (SenseItem)sender;
            var parent = (XFPanelList)button.Parent;

            parent.ClearItem(button);

            var worker = new XFWorkerLoadLikes(button.Tag.ToString());
            var loading = new XFItemLoading(worker);

            loading.WorkFinished += NextLikesClickLoadingWorkFinished;
            button.Dispose();
            parent.Add(loading);
        }

        private static void NextLikesClickLoadingWorkFinished(object sender, WorkerEventArgs e)
        {
            FBPost feed = null;
            var loading = (XFItemLoading)sender;

            if (e.Worker is XFWorkerLoadLikes)
                feed = ((XFWorkerLoadLikes)e.Worker).ParsedPost;

            var par = loading.Parent as XFPanelList;

            if (par != null && !par.IsDisposed)
                par.Invoke(new Action(() =>
                {
                    par.ClearItemsAfterWaiting(loading);

                    if (feed == null || feed.PeopleWhoLiked.data == null) return;
                    LoadLikes(par, feed, -1);

                    if (feed.PeopleWhoLiked.paging == null) return;
                    var next = new SenseItem
                    {
                        Tag = feed.PeopleWhoLiked.paging.next,
                        MainText = Settings.LocalizationStrings.newerLikes
                    };

                    next.Click += NextLikesClick;
                    next.Style.BackgroundColor = Color.White;
                    par.Add(next);
                }));
        }

        private int MesText(string text, ref int currWidth, ref int temp, ref int currY, int bodyWidth)
        {
            return MesText(text, ref currWidth, ref temp, ref currY, bodyWidth, Style.TextFont);
        }

        private int MesText(string text, ref int currWidth, ref int temp, ref int currY, int bodyWidth, Font f)
        {
            int ret = 0;
            if (!string.IsNullOrEmpty(text))
            {
                ret = f.MeasureString(text, new Rectangle(0, 0, currWidth, 0)).Height;
                temp += ret + _lineSpace;
                currY += ret + _lineSpace;
            }

            if (temp > _postPictureWidth)
                currWidth = bodyWidth;

            return ret;
        }

        private static string GetToFromString(FBPost post)
        {
            if (post.from == null) return "";
            string ret = post.from.name;

            if (post.to == null)
                return ret;

            string to = "";

            for (int i = 0; i < _maxFriends && i < post.to.data.Count; i++)
            {
                FBProxyPerson person = post.to.data[i];
                if (string.IsNullOrEmpty(to))
                    to += person.name;
                else
                    to += ", " + person.name;
            }
            if (post.to.data.Count > _maxFriends)
                to += string.Format(" " + Settings.LocalizationStrings.AndMoreUsers, post.to.data.Count - _maxFriends);

            if (!string.IsNullOrEmpty(to))
                ret += " > " + to;
            return ret;
        }

        private void WritePostTime(Graphics g)
        {
            using (var b = new SolidBrush(Color.DarkSlateGray))
            {
                string display = Post.created_time >= Post.updated_time ? Post.created_time.ToFacebookTime() : Post.updated_time.ToFacebookTime();
                int currX = _timeRec.X;
                int currY = _timeRec.Y;

                if (!string.IsNullOrEmpty(Post.icon))
                {
                    DrawIcon(Post.icon, g, new Rectangle(_timeRec.X - _left, _timeRec.Y, _iconWidth, _iconWidth));
                    currX += _iconWidth + _lineSpace;
                }

                g.DrawString(display, _timeFont, b, currX - _left, currY);
            }
        }

        private void DrawActions(Graphics g)
        {
            int currX = 0;
            int currY = _timeRec.Y + _timeRec.Height + _lineSpace;
            using (var b = new SolidBrush(Color.Navy))
            {
                if (Post == null) return;

                currX += _pictureWidth;
                using (var f = new Font(Style.TextFont.Name, Style.TextFont.Size - 0.5f, FontStyle.Bold))
                {
                    string viewLikes = "View " + Settings.LocalizationStrings.Likes;
                    string comments;

                    if (Post.comments == null)
                        comments = "0 " + Settings.LocalizationStrings.Comments;
                    else if (Post.comments.count == 1)
                        comments = string.Format("{0} " + Settings.LocalizationStrings.Comment, Post.comments.count);
                    else
                        comments = string.Format("{0} " + Settings.LocalizationStrings.Comments, Post.comments.count);

                    string likes;

                    likes = Post.PeopleWhoLiked.count == 1
                                ? string.Format("{0} " + Settings.LocalizationStrings.Like, Post.PeopleWhoLiked.count)
                                : string.Format("{0} " + Settings.LocalizationStrings.Likes, Post.PeopleWhoLiked.count);

                    SizeF mesActCom = g.MeasureString(comments, f);
                    SizeF mesActLikes = g.MeasureString(likes, f);

                    if (Post.actions.Any(p => p.name == "Comment") && Post.actions.Any(p => p.name == "Like"))
                    {
                        g.DrawAlphaFirstPix(_actionImage, 0, currY);
                        //DrawUI("post_comments", g, new Rectangle(0, currY, _postRec.Width, _postRec.Height));
                        currY += (_actionImage.Height / 2) - _lineSpace;
                    }

                    if (Post.actions.Any(p => p.name == "Like"))
                    {
                        _likesRec = new Rectangle((GetWidth() / 2) - (int)mesActLikes.Width - (_lineSpace * 2) - _left, currY,
                                                  (int)mesActLikes.Width, (int)mesActLikes.Height);
                        g.DrawString(likes, f, b, _likesRec.X, _likesRec.Y);
                    }

                    if (!Post.actions.Any(p => p.name == "Comment")) return;

                    _commentsRec = new Rectangle(GetWidth() - (int)mesActCom.Width - currX - _left, currY, (int)mesActCom.Width,
                                                 (int)mesActCom.Height);

                    if (_isInCommentPannel || Post.type == "comment")
                        g.DrawString(viewLikes, f, b, _commentsRec.X, _commentsRec.Y);
                    else
                        g.DrawString(comments, f, b, _commentsRec.X, _commentsRec.Y);
                }
            }
        }

        private void GetActionImage()
        {
            _actionImage = GetImageUI("post_comments");

            if (XFGraphics.GetScreenResolutionNotRotated() != ScreenResolution.QVGA) return;

            var temp = _actionImage.Scale(.5);
            _actionImage.Dispose();
            _actionImage = temp;
        }

        private void SlideRight()
        {
            _inSwipe = false;

            while (_left > 5 && !_inSwipe)
            {
                Invalidate();
                _left = _left / 3;
                Parent.Invalidate();
                Application.DoEvents();
            }
            _delete.State = XFItemState.Normal;
            _left = 0;
        }

        private void SlideLeft()
        {
            _inSwipe = true;

            while (_left < _maxLeft - 5 && _inSwipe)
            {
                Invalidate();
                _left += (_maxLeft - _left) / 3;
                Parent.Invalidate();
                Application.DoEvents();
            }
            _left = _maxLeft;
        }
    }

    internal enum XFItemPostSelected
    {
        Profile,
        Picture,
        Link,
        Comment,
        Like,
        Inbox,
        Groups
    }
}

#pragma warning restore 1591